Skip to content

lib,src,test,doc: add node:ffi module#62072

Open
cjihrig wants to merge 19 commits intonodejs:mainfrom
cjihrig:ffi
Open

lib,src,test,doc: add node:ffi module#62072
cjihrig wants to merge 19 commits intonodejs:mainfrom
cjihrig:ffi

Conversation

@cjihrig
Copy link
Copy Markdown
Contributor

@cjihrig cjihrig commented Mar 2, 2026

This is not ready for review yet. Just opening to see if this is something the project is still interested in.

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/gyp
  • @nodejs/security-wg

@nodejs-github-bot nodejs-github-bot added build Issues and PRs related to build files or the CI. dependencies Pull requests that update a dependency file. needs-ci PRs that need a full CI run. labels Mar 2, 2026
@anonrig
Copy link
Copy Markdown
Member

anonrig commented Mar 2, 2026

Yes

Copy link
Copy Markdown
Member

@Qard Qard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very cool! I'm glad to see someone has picked this back up. 🙂

I did a quick review and it all looks good. My only comment is there seems to be a bunch of static strings and a private symbol which we might want to define in env_properties.h.

@cjihrig cjihrig force-pushed the ffi branch 2 times, most recently from 9462e4d to 631d73a Compare March 10, 2026 03:46
@cjihrig cjihrig added the request-ci Add this label to start a Jenkins CI on a PR. label Mar 18, 2026
@github-actions github-actions bot added request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Mar 18, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Failed to start CI
   ⚠  No approving reviews found
   ✘  Refusing to run CI on potentially unsafe PR
https://github.com/nodejs/node/actions/runs/23272564448

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

anonrig
anonrig previously approved these changes Mar 18, 2026
@anonrig anonrig added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. labels Mar 18, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Mar 18, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@cjihrig
Copy link
Copy Markdown
Contributor Author

cjihrig commented Mar 18, 2026

@anonrig I cancelled that CI run to save resources. I started https://ci.nodejs.org/job/node-test-pull-request/71877/ manually, and it's currently running.

@jasnell jasnell dismissed anonrig’s stale review March 19, 2026 00:26

given that this is still draft and @cjihrig indicated it's not ready for review, a sign off is not yet appropriate.

mcollina
mcollina previously approved these changes Mar 19, 2026
Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Mar 19, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@jasnell jasnell dismissed mcollina’s stale review March 19, 2026 03:40

given that this is still draft and @cjihrig indicated it's not ready for review, a sign off is not yet appropriate.

@jasnell
Copy link
Copy Markdown
Member

jasnell commented Mar 19, 2026

@cjihrig ... definitely interested in seeing ffi land. I was hoping @bengl's prior efforts would make progress. Once you feel this is ready to go, I'll be happy to review.

@cjihrig cjihrig marked this pull request as ready for review April 1, 2026 14:41
Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina
Copy link
Copy Markdown
Member

mcollina commented Apr 1, 2026

@cjihrig @ShogunPanda this now conflicts, can you rebase?

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.66%. Comparing base (e775989) to head (2587eef).
⚠️ Report is 43 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62072      +/-   ##
==========================================
- Coverage   89.71%   89.66%   -0.06%     
==========================================
  Files         695      706      +11     
  Lines      214546   217789    +3243     
  Branches    41082    41665     +583     
==========================================
+ Hits       192487   195279    +2792     
- Misses      14116    14439     +323     
- Partials     7943     8071     +128     
Files with missing lines Coverage Δ
lib/ffi.js 95.73% <ø> (ø)
lib/internal/bootstrap/realm.js 96.21% <ø> (+<0.01%) ⬆️
lib/internal/process/permission.js 100.00% <ø> (ø)
lib/internal/process/pre_execution.js 98.63% <ø> (+1.40%) ⬆️
src/env.cc 85.30% <ø> (+0.11%) ⬆️
src/ffi/data.cc 78.77% <ø> (ø)
src/ffi/types.cc 59.67% <ø> (ø)
src/node_binding.cc 82.74% <ø> (ø)
src/node_builtins.cc 76.09% <ø> (-0.15%) ⬇️
src/node_ffi.cc 69.07% <ø> (ø)
... and 8 more

... and 71 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

cjihrig and others added 6 commits April 6, 2026 08:12
* src,deps,test: various improvements

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* deps,test: fixed failures

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* deps,test: fixed failures

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* deps,test: fixed failures

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* deps,test: fixed failures

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* doc,lib: fixed failures

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* deps: fixed failures

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* test: fixed failures

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

---------

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
* test: fixed build on Windows

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* test: fixed build on Windows

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* test: fixed build on Windows

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* test: fixed build on Windows

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* test: removed useless file

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

---------

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
Signed-off-by: Paolo Insogna <paolo@cowtech.it>
Signed-off-by: Paolo Insogna <paolo@cowtech.it>
Signed-off-by: Paolo Insogna <paolo@cowtech.it>
@ShogunPanda ShogunPanda added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 6, 2026
Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 6, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
@ShogunPanda ShogunPanda added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 7, 2026
Signed-off-by: Paolo Insogna <paolo@cowtech.it>
Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 7, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
@ShogunPanda ShogunPanda added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 9, 2026
Signed-off-by: Paolo Insogna <paolo@cowtech.it>
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Other targets require building Node.js against a shared libffi with
`--shared-ffi`. The unofficial GN build does not support `node:ffi`.

When using the [Permission Model][], FFI APIs are
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should permissions have an option to restrict which files or symbols can be loaded?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, it could potentially be a very long list.
Anyway, I'm open to reconsider this in a future PR, but I think we can start with this as a starting point.

Supported type names:

* `void`
* `i8`, `int8`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why introduce any aliases? Seems like extra mental overhead to remember that there's two ways to spell the same thing?

Should we export a constant with available types?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About the first question: it's to make transition smooth from other languages or runtime. You don't have to remember both, you just use what you already know.

About the second: that's a good suggestion. I will add it!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO while aliases make writing code easier and more familiar (you write what you're familiar with), they make reading code harder, especially when you read other peoples code (you're reading their conventions and checking when they mean the same thing and when they mean different).

I think good docs, @types/node, and the constant we add will help the writing UX with fewer downsides.

Adding aliases would be backward compatible, but removing them would not, so I'd prefer starting with no aliases.
(I'm just another community member that wants to see node:ffi land, not a required reviewer)

through reentrant JavaScript such as FFI callbacks. Doing so may crash the
process, produce incorrect output, or corrupt memory.

The `char` type follows the platform C ABI. On platforms where plain C `char`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include an example (or function) to check the platform c abi?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is unnecessary. First of all, this is transparent to node:ffi so users won't really care about this. The few that might care probably know which platforms they're developing on.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the request for a suffix helper are intended for code that doesn't know what platforms it will run on - I think developers would write similar code to map platform to C ABI or dll suffix which seems like a good opportunity for a built in helper.


Supported fields:

* `result`, `return`, or `returns` for the return type.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an explanation why there's more than one way to spell this? Compat with other ffi libraries? If so, we should document that, tho I'd rather pick one or drop compat goals.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above: no need to, just trying to use the principle of least surprise here. Other runtimes use different conventions so I'm trying to please anybody, since there is no hard requirement on the ABI side.

);
const libraryPath = path.join(
fixtureBuildDir,
process.platform === 'win32' ? 'ffi_test_library.dll' :
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should node:ffi export a suffix constant?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. This is just used in tests, I guess people know which file they are loading :)

@@ -706,7 +719,7 @@ function initializePermission() {
const { availableFlags } = require('internal/process/permission');
ArrayPrototypeForEach(availableFlags(), (flag) => {
const value = getOptionValue(flag);
if (value.length) {
if (value === true || value?.length) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change required? There's already boolean permission flags

offset, or writing through a stale pointer can corrupt memory or crash the
process.

## `ffi.toString(pointer)`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have an optional max length?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure to be honest. The underlying C++ method will return an empty string, if length>maxLength, which I find counter-intuitive.
I wouldn't for now, but we can eventually change in a follow up PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Issues and PRs related to build files or the CI. dependencies Pull requests that update a dependency file. needs-ci PRs that need a full CI run. request-ci Add this label to start a Jenkins CI on a PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants